#ifndef PERMISSION_H
#define PERMISSION_H

namespace ftp
{

/**
 * Permission definition for user to operate file or directory(abbr. dir)
 */
enum class Permission : int
{
	FileRead   = ((static_cast<int>(1)) << 0),  /* Download files */
	FileWrite  = ((static_cast<int>(1)) << 1),  /* Upload files as new files */
	FileAppend = ((static_cast<int>(1)) << 2),  /* Upload files thath get appended to existing files */
	FileDelete = ((static_cast<int>(1)) << 3),  /* Delete existing files or overwrite an existing file */
	FileRename = ((static_cast<int>(1)) << 4),  /* Rename existing files */

	DirList    = ((static_cast<int>(1)) << 5),  /* Retrieve the content of directories */
	DirCreate  = ((static_cast<int>(1)) << 6),  /* Create new directories */
	DirDelete  = ((static_cast<int>(1)) << 7),  /* Delete existing directories */
	DirRename  = ((static_cast<int>(1)) << 8),  /* Rename existing directories */

	All        = (FileRead | FileWrite | FileAppend | FileDelete | FileRename 
	| DirList | DirCreate | DirDelete | DirRename),
	ReadOnly   = (FileRead | DirList),
	None       = 0
};

inline Permission operator~(Permission a)
{
	return static_cast<Permission>(~static_cast<int>(a));
}

inline Permission operator|(Permission a, Permission b)
{
	return static_cast<Permission>(static_cast<int>(a) | static_cast<int>(b));
}

inline Permission operator&(Permission a, Permission b)
{
	return static_cast<Permission>(static_cast<int>(a) & static_cast<int>(b));
}

inline Permission operator^(Permission a, Permission b)
{
	return static_cast<Permission>(static_cast<int>(a) ^ static_cast<int>(b));
}

inline Permission& operator|=(Permission& a, Permission b)
{
	int ia = static_cast<int>(a);
	int ib = static_cast<int>(b);
	ia |= ib;
	a = static_cast<Permission>(ia);
	return a;
}

inline Permission& operator&=(Permission& a, Permission b)
{
	int ia = static_cast<int>(a);
	int ib = static_cast<int>(b);
	ia &= ib;
	a = static_cast<Permission>(ia);
	return a;
}

inline Permission& operator^=(Permission& a, Permission b)
{
	int ia = static_cast<int>(a);
	int ib = static_cast<int>(b);
	ia ^= ib;
	a = static_cast<Permission>(ia);
	return a;
}

} // namespace ftp

#endif // !PERMISSION_H
